<script lang="ts" setup>
import { computed, onMounted, onUnmounted, onUpdated, ref } from 'vue'
import { ns } from '@/utils/storage'
import MarkdownIt from 'markdown-it'
import MdKatex from '@vscode/markdown-it-katex'
import MdLinkAttributes from 'markdown-it-link-attributes'
import MdMermaid from 'mermaid-it-markdown'
import hljs from 'highlight.js'
import { useBasicLayout } from '@/hooks/useBasicLayout'
import { t } from '@/locales'
import { copyToClip } from '@/utils/copy'
import { 
  EditorJsParser
} from 'editorjs-component-vue';
import Vditor from 'vditor';
import 'vditor/dist/index.css';

// 2. 获取DOM引用
const vditor = ref()



interface Props {
  inversion?: boolean
  error?: boolean
  text?: string
  loading?: boolean
  asRawText?: boolean
  last?: boolean
}
interface Emit {
  (ev: 'update:text',params:any): void
}

const emit = defineEmits<Emit>()
const props = defineProps<Props>()
// 3. 在组件初始化时，就创建Vditor对象，并引用
onMounted(() => {
  if(props.last){
      setTimeout(()=>{
        vditor.value = new Vditor('initvditor',{
          // height: '50vh',
          width: '1000px',
          value: '可选模式：sv, ir, wysiwyg',
          mode:'wysiwyg',
        })
      },0)
  }
})
const { isMobile } = useBasicLayout()

const textRef = ref<HTMLElement>()
const textNew = computed(() =>{ 
  
  // return props.text
  // return `
  // <H1>123123</H1>
  
  // `
    const value = `
    # ChatGPT Web

> 声明：此项目只发布于 GitHub，基于 MIT 协议，免费且作为开源学习使用。并且不会有任何形式的卖号、付费服务、讨论群、讨论组等行为。谨防受骗。

 [English](README.md)

![cover](./docs/c1.png)
    `
  if (!props.asRawText) {
    // 对数学公式进行处理，自动添加 $$ 符号
    const escapedText = escapeBrackets(escapeDollarNumber(value))
    console.log('[ escapedText ] >', mdi.render(escapedText))
    return mdi.render(escapedText)
  }
  return value
  })
const mdi = new MarkdownIt({
  html: false,
  linkify: true,
  highlight(code, language) {
    const validLang = !!(language && hljs.getLanguage(language))
    if (validLang) {
      const lang = language ?? ''
      return highlightBlock(hljs.highlight(code, { language: lang }).value, lang)
    }
    return highlightBlock(hljs.highlightAuto(code).value, '')
  },
})

mdi.use(MdLinkAttributes, { attrs: { target: '_blank', rel: 'noopener' } }).use(MdKatex).use(MdMermaid)

const wrapClass = computed(() => {
  return [
    'text-wrap',
    'min-w-[20px]',
    'rounded-md',
    isMobile.value ? 'p-2' : 'px-3 py-2',
    props.inversion ? 'bg-[#d2f9d1]' : 'bg-[#f4f6f8]',
    props.inversion ? 'dark:bg-[#a1dc95]' : 'dark:bg-[#1e1e20]',
    props.inversion ? 'message-request' : 'message-reply',
    { 'text-red-500': props.error },
  ]
})

const text = computed(() => {
  const value = props.text ?? ''
  if (!props.asRawText) {
    // 对数学公式进行处理，自动添加 $$ 符号
    const escapedText = escapeBrackets(escapeDollarNumber(value))
    return mdi.render(escapedText)
  }
  return value
})

function highlightBlock(str: string, lang?: string) {
  return `<pre class="code-block-wrapper"><div class="code-block-header"><span class="code-block-header__lang">${lang}</span><span class="code-block-header__copy">${t('chat.copyCode')}</span></div><code class="hljs code-block-body ${lang}">${str}</code></pre>`
}

function addCopyEvents() {
  if (textRef.value) {
    const copyBtn = textRef.value.querySelectorAll('.code-block-header__copy')
    copyBtn.forEach((btn) => {
      btn.addEventListener('click', () => {
        const code = btn.parentElement?.nextElementSibling?.textContent
        if (code) {
          copyToClip(code).then(() => {
            btn.textContent = t('chat.copied')
            setTimeout(() => {
              btn.textContent = t('chat.copyCode')
            }, 1000)
          })
        }
      })
    })
  }
}

function removeCopyEvents() {
  if (textRef.value) {
    const copyBtn = textRef.value.querySelectorAll('.code-block-header__copy')
    copyBtn.forEach((btn) => {
      btn.removeEventListener('click', () => { })
    })
  }
}

function escapeDollarNumber(text: string) {
  let escapedText = ''

  for (let i = 0; i < text.length; i += 1) {
    let char = text[i]
    const nextChar = text[i + 1] || ' '

    if (char === '$' && nextChar >= '0' && nextChar <= '9')
      char = '\\$'

    escapedText += char
  }

  return escapedText
}

function escapeBrackets(text: string) {
  const pattern = /(```[\s\S]*?```|`.*?`)|\\\[([\s\S]*?[^\\])\\\]|\\\((.*?)\\\)/g
  return text.replace(pattern, (match, codeBlock, squareBracket, roundBracket) => {
    if (codeBlock)
      return codeBlock
    else if (squareBracket)
      return `$$${squareBracket}$$`
    else if (roundBracket)
      return `$${roundBracket}$`
    return match
  })
}

onMounted(() => {
  addCopyEvents()
})

onUpdated(() => {
  addCopyEvents()
})

onUnmounted(() => {
  removeCopyEvents()
})

interface ChangeEvent {
  json: any;
}
// editorjs-js-component 在线编辑md工具
const blockList = ref<Array<any>>([]) // 使用 any 类型作为占位符
const jsonBlockList = {
      "time": 1721207440583,
      "blocks": [
      {
          "id": "introduction",
          "type": "h2",
          "data": {
              "text": "介绍",
              "level": 2
          },
          "tunes": {
              "alignBlockTune": {
                  "alignment": "left"
              }
          }
      },
      {
          "id": "double_model_support",
          "type": "paragraph",
          "data": {
              "text": "支持双模型，提供了两种非官方 `ChatGPT API` 方法"
          }
      },
      {
          "id": "api_table",
          "type": "table",
          "data": {
              "withHeadings": true,
              "content": [
                  [
                      "方式",
                      "免费？",
                      "可靠性",
                      "质量"
                  ],
                  [
                      "ChatGPTAPI(gpt-3.5-turbo-0301)",
                      "否",
                      "可靠",
                      "相对较笨"
                  ],
                  [
                      "ChatGPTUnofficialProxyAPI(网页 accessToken)",
                      "是",
                      "相对不可靠",
                      "聪明"
                  ]
              ]
          }
      }
    ],
      "version": "2.28.2"
  }
const data = ref<Array<any>>([])
let rangeSelection;
const editorChange = ({ json }:ChangeEvent) => {
  console.log('[ json ] >', json)
  blockList.value = json.blocks

  
  // {
  //     "time": 1721207440583,
  //     "blocks": [],
  //     "version": "2.28.2"
  // }
  
  
  
}

const i18nMessage = {
  "ui": {
    "blockTunes": {
      "toggler": {
        "Click to tune": "点击调整",
        "or drag to move": "或者拖动移动"
      }
    },
    "inlineToolbar": {
      "converter": {
        "Convert to": "转换为"
      }
    },
    "toolbar": {
      "toolbox": {
        "Add": "添加"
      }
    }
  },
  "toolNames": {
    "Text": "文本",
    "Heading": "标题",
    "List": "有序列表",
    "NestedList": "无序列表",
    "Warning": "警告",
    "Checklist": "清单",
    "Quote": "引用",
    "Code": "代码",
    "Delimiter": "分隔符",
    "Raw HTML": "原始HTML",
    "Table": "表格",
    "Link": "链接",
    "Marker": "标记",
    "Bold": "加粗",
    "Italic": "斜体",
    "Image": "图片"
  },
  "tools": {
    "warning": {
      "Title": "标题",
      "Message": "消息"
    },
    "link": {
      "Add a link": "添加链接"
    },
    "stub": {
      "The block can not be displayed correctly.": "该块不能正确显示"
    }
  },
  "blockTunes": {
    "delete": {
      "Delete": "删除"
    },
    "moveUp": {
      "Move up": "向上移动"
    },
    "moveDown": {
      "Move down": "向下移动"
    }
  }
}
const toolConfig = {

}

const isvditor = ref<boolean>(false)

const editorMdChange = ()=>{
  isvditor.value = true
   ns.set('vditorvditor', props.text)
   setTimeout(()=>{

    vditor.value = new Vditor('vditor',{
      // height: '50vh',
      width: '1000px',
      value: '可选模式：sv, ir, wysiwyg',
      mode:'wysiwyg',
    })
   },0)
}
const saveMdChange = ()=>{
  isvditor.value = false
  // emit('update:text',ns.get('vditorvditor'))
  // textShow.value = ns.get('vditorvditor')
  // props.text = ns.get('vditorvditor');
   console.log('[ ns.get(vditorvditor) ] >', ns.get('vditorvditor'))

}
defineExpose({
  editorMdChange,saveMdChange
})
</script>

<template>
  <div class="text-black" :class="wrapClass">
    <div id="initvditor" class="vditorHide"></div>
    <div id="vditor"  v-if="!inversion&&isvditor"></div>
  
    <div ref="textRef" class="leading-relaxed break-words"  v-if="!isvditor">
      <div v-if="!inversion">
        <!-- 原有聊天回答标签，可以渲染md文件-->
        <div v-if="!asRawText" class="markdown-body" style="width: 1000px;" :class="{ 'markdown-body-generate': loading }" v-html="text" />

        <!-- 编辑md工具 -->

        <!-- 新的可编辑交互组件，不能渲染md文件 -->
        <!-- <div v-if="!false"  class="markdown-body" :class="{ 'markdown-body-generate': loading }">
            <EditorJsVue
              style="width: 1000px;"
              ref="editor"
              :data="jsonBlockList"
              :messages="i18nMessage"
              :tool-config="toolConfig"
              @changeData="editorChange"
            />
        </div> -->
        <div v-else class="whitespace-pre-wrap" v-text="text" />
      </div>
      <!-- 提问标签 -->
      <div v-else class="whitespace-pre-wrap" v-text="text" />
    </div>
  </div>
</template>

<style lang="less">
@import url(./style.less);
.vditorHide{
  position: absolute;
  z-index: -1;
}
</style>
